#ifndef __SelectionVariables_h__
#define __SelectionVariables_h__

#pragma once

/*
	This file implements variable value and variable declaration collections.
*/

typedef uint32 SelectionVariableID;

class BlockyXmlBlocks;
class SelectionVariableDeclarations;

class SelectionVariables
{
public:
	SelectionVariables();

	bool GetVariable(const SelectionVariableID& variableID, bool* value) const;
	bool SetVariable(const SelectionVariableID& variableID, bool value);

	void ResetChanged(bool state = false);
	bool Changed() const;

	void Swap(SelectionVariables& other);

	void Serialize(TSerialize ser);

	void DebugDraw(bool history, const SelectionVariableDeclarations& declarations) const;

private:
	struct Variable
	{
		Variable()
			: value(false)
		{
		}

		bool value;

		void Serialize(TSerialize ser)
		{
			ser.Value("value", value);
		}
	};

	struct variable_hash_traits :
		public stl::hash_uint32
	{
		enum
		{
			bucket_size = 1,
			min_buckets = 16
		};
	};

	typedef stl::hash_map<SelectionVariableID, Variable, variable_hash_traits> Variables;
	Variables m_variables;

	bool m_changed;

	struct VariableChangeEvent
	{
		VariableChangeEvent(const CTimeValue& _when, const SelectionVariableID _variableID, bool _value)
			: when(_when)
			, variableID(_variableID)
			, value(_value)
		{
		}

		CTimeValue when;
		SelectionVariableID variableID;
		bool value;
	};

	typedef std::deque<VariableChangeEvent> History;
	History m_history;
};


class SelectionVariableDeclarations
{
public:
	struct VariableDescription
	{
		VariableDescription(const char* _name)
			: name(_name)
		{
		}

		string name;
	};
	typedef std::map<SelectionVariableID, VariableDescription> VariableDescriptions;

	SelectionVariableDeclarations();
	bool LoadFromXML(const _smart_ptr<BlockyXmlBlocks>& blocks, const XmlNodeRef& rootNode, const char* scopeName, const char* fileName);
	
	bool IsDeclared(const SelectionVariableID& variableID) const;

	SelectionVariableID GetVariableID(const char* name) const;
	const VariableDescription& GetVariableDescription(const SelectionVariableID& variableID) const;

	const SelectionVariables& GetDefaults() const;
	const VariableDescriptions& GetDescriptions() const;

private:
	VariableDescriptions m_descriptions;
	SelectionVariables m_defaults;
};

#endif
